package com.byd.android.Socket;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    private static final String TAG = "SocketServer";

    public static final int RETURN_MESSAGE = 0x101;

    public static final int DISCONNECT = 0x102;


    private ServerSocket server;
    private Socket socket;
    private InputStream inputStream;
    private PrintWriter out;
    private String str=null;
    private OutputStream outputStream;
    //private boolean isClint=false;
    private SendMsg2 mSendMsg2;
    private Handler mSocketHandler;
    private static final int SEND_FINISHED = 0x202;
    private static final int CLIENT_EXIT = 0x203;
    public static Handler ServerHandler;

    //服务端绑定端口号
    public SocketServer(int port) throws IOException {
        server= new ServerSocket (port);
        mSocketHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case SEND_FINISHED:
                        resetSendMsg();
                        break;
                    case CLIENT_EXIT:
                        beginListen2();
                        break;
                }
            }
        };
    }

    //服务端监听
    public void beginListen2(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket=server.accept();
                    Log.d(TAG, "服务端连接成功");
                    ReceiveMsg2(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                    mSocketHandler.sendEmptyMessage(CLIENT_EXIT);
                }
            }
        }).start();
    }

    //服务端收到数据，返回到主界面
    public void returnMessage(byte[] bytes){
        try {
            String text = new String(bytes, "UTF-8");
            Log.d(TAG, "returnMessage: " + text);
            Message msg=new Message ();
            msg.obj=bytes;
            ServerHandler.sendMessage (msg);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }


    //服务端发送消息方法
    public void sendMsg2(final String str)
    {
        Log.i("发送消息方法",str);         //1
        Log.d(TAG, "mSendMsg2=" + mSendMsg2 + " socket .isClosed()=" + socket .isClosed());
        if (mSendMsg2 == null) {
            if (isAvailable(socket)) {
                mSendMsg2 = new SendMsg2(socket, str);
            }
            mSendMsg2.start();
        }
    }

    private void resetSendMsg() {
        mSendMsg2 = null;
    }

    //服务端接收消息方法
    public void ReceiveMsg2(Socket s)
    {
        Log.i("接收消息方法","");
        new ReceiveMsg2(s).start();
    }

    //接收消息线程
    class ReceiveMsg2 extends Thread{
        Socket response;

        public ReceiveMsg2(Socket response) {
            this.response = response;
        }

        @Override
        public void run() {
            try {
                Log.d("收到线程","");
                // String address = response.getInetAddress().getHostAddress();
                InputStream inputStream = response.getInputStream();//得到从服务端的输入流
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buff = new byte[1024];
                    int size = -1;
                while((size = inputStream.read(buff)) != -1) {
                    Log.d(TAG, "read buff start! size=" + size);
                    if (size > 0 && buff[size-1] == 10) {
                        baos.write(buff, 0, size - 1);
                        returnMessage(baos.toByteArray());
                        baos.reset();
                        Log.d(TAG, "reset baos: " + baos.toByteArray().length);
                        String text = new String(baos.toByteArray(), "UTF-8");
                        Log.d(TAG, "read buff end! text=" + text);
                        continue;
                    }
                    baos.write(buff, 0, size);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
           closeSocket(response);
            mSocketHandler.sendEmptyMessage(CLIENT_EXIT);
        }
    }


    //发送消息的线程
    class SendMsg2 extends Thread{
        Socket response;
        String str;

        public SendMsg2(Socket response,String str) {
            this.response = response;
            this.str = str;
        }

        @Override
        public void run() {
            try {
                Log.d(TAG,"send str: " + str.length());      //1
                OutputStream outputStream = response.getOutputStream();//输出流，向客户端发送消息
                byte[] data = str.getBytes("UTF-8");
                int offset = 0;
                while(offset < data.length) {
                    int len = Math.min(data.length - offset, 1024);
                    outputStream.write(data, offset, len);
                    outputStream.flush();
                    offset += len;
                }
                outputStream.write("\n".getBytes("UTF-8"));
                outputStream.flush();
                //关闭相对应的资源
//            bufferedReader.close();
//            bufferedWriter.close();
//            outputStream.close();
//            response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mSocketHandler.sendEmptyMessage(SEND_FINISHED);
        }
    }

    public static void closeSocket(Socket sock) {
        if(sock != null) {
            try {
                Log.d(TAG, "The socket will close: " + sock.toString());
                sock.shutdownInput();
                sock.shutdownOutput();
                sock.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void close() {
        Log.d(TAG, "SocketServer close!");
        closeSocket(socket);
        try {
            if (server != null) {
                server.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public boolean isAvailable(Socket socket) {
        return  socket!= null
                && socket.isConnected()
                && !socket.isInputShutdown()
                && !socket.isOutputShutdown()
                && !socket.isClosed();
    }

}
